package com.sjw.workflow.dag;

import com.sjw.workflow.core.WorkflowContext;
import java.util.List;
import java.util.ArrayList;
import java.util.Objects;

/**
 * 逻辑表达式接口
 * 支持AND、OR、NOT三种逻辑操作
 */
public interface LogicalExpression {
    
    /**
     * 评估逻辑表达式
     * @param context 工作流上下文
     * @return 表达式结果
     */
    boolean evaluate(WorkflowContext context);
    
    /**
     * 创建AND表达式
     */
    static LogicalExpression and(LogicalExpression... expressions) {
        return new AndExpression(expressions);
    }
    
    /**
     * 创建OR表达式
     */
    static LogicalExpression or(LogicalExpression... expressions) {
        return new OrExpression(expressions);
    }
    
    /**
     * 创建NOT表达式
     */
    static LogicalExpression not(LogicalExpression expression) {
        return new NotExpression(expression);
    }
    
    /**
     * 创建Agent完成条件
     */
    static LogicalExpression agentCompleted(String agentId) {
        return new AgentCompletedExpression(agentId);
    }
    
    /**
     * 创建Agent成功条件
     */
    static LogicalExpression agentSuccessful(String agentId) {
        return new AgentSuccessfulExpression(agentId);
    }
}

/**
 * AND逻辑表达式
 */
class AndExpression implements LogicalExpression {
    private final List<LogicalExpression> expressions;
    
    public AndExpression(LogicalExpression... expressions) {
        this.expressions = new ArrayList<>();
        for (LogicalExpression expr : expressions) {
            if (expr != null) {
                this.expressions.add(expr);
            }
        }
    }
    
    @Override
    public boolean evaluate(WorkflowContext context) {
        if (expressions.isEmpty()) {
            return true;
        }
        
        for (LogicalExpression expr : expressions) {
            if (!expr.evaluate(context)) {
                return false;
            }
        }
        return true;
    }
    
    @Override
    public String toString() {
        return "AND(" + String.join(", ", expressions.stream().map(Objects::toString).toArray(String[]::new)) + ")";
    }
}

/**
 * OR逻辑表达式
 */
class OrExpression implements LogicalExpression {
    private final List<LogicalExpression> expressions;
    
    public OrExpression(LogicalExpression... expressions) {
        this.expressions = new ArrayList<>();
        for (LogicalExpression expr : expressions) {
            if (expr != null) {
                this.expressions.add(expr);
            }
        }
    }
    
    @Override
    public boolean evaluate(WorkflowContext context) {
        if (expressions.isEmpty()) {
            return false;
        }
        
        for (LogicalExpression expr : expressions) {
            if (expr.evaluate(context)) {
                return true;
            }
        }
        return false;
    }
    
    @Override
    public String toString() {
        return "OR(" + String.join(", ", expressions.stream().map(Objects::toString).toArray(String[]::new)) + ")";
    }
}

/**
 * NOT逻辑表达式
 */
class NotExpression implements LogicalExpression {
    private final LogicalExpression expression;
    
    public NotExpression(LogicalExpression expression) {
        this.expression = expression;
    }
    
    @Override
    public boolean evaluate(WorkflowContext context) {
        return expression == null || !expression.evaluate(context);
    }
    
    @Override
    public String toString() {
        return "NOT(" + expression + ")";
    }
}

/**
 * Agent完成条件表达式
 */
class AgentCompletedExpression implements LogicalExpression {
    private final String agentId;
    
    public AgentCompletedExpression(String agentId) {
        this.agentId = agentId;
    }
    
    @Override
    public boolean evaluate(WorkflowContext context) {
        return context.isAgentCompleted(agentId);
    }
    
    @Override
    public String toString() {
        return "COMPLETED(" + agentId + ")";
    }
}

/**
 * Agent成功条件表达式
 */
class AgentSuccessfulExpression implements LogicalExpression {
    private final String agentId;
    
    public AgentSuccessfulExpression(String agentId) {
        this.agentId = agentId;
    }
    
    @Override
    public boolean evaluate(WorkflowContext context) {
        return context.isAgentSuccessful(agentId);
    }
    
    @Override
    public String toString() {
        return "SUCCESSFUL(" + agentId + ")";
    }
}
